class Electron extends Point{
  float fx,fy,fz;
  int fn;
  Vector v;
  boolean locked = false;
  int faces = 0;
  Electron(float $x,float $y,float $z){
    super($x,$y,$z);
    v = new Vector($x,$y,$z);
    reset_forces();
  }
  void repel(Electron[] $electrons){
    for(int i=0;i<$electrons.length;i++){
      if($electrons[i]!=this){
        float d = get_distance_to($electrons[i].x,$electrons[i].y,$electrons[i].z);
        if(d>0){
          float f = force/sq(d);
          float dx = $electrons[i].x-x;
          float dy = $electrons[i].y-y;
          float dz = $electrons[i].z-z;
          if(!$electrons[i].locked){
            $electrons[i].add_force((-f/2)*(dx/d),(-f/2)*(dy/d),(-f/2)*(dz/d));
          }
          if(!locked){
            add_force((f/2)*(dx/d),(f/2)*(dy/d),(f/2)*(dz/d));
          }
        }
      }
    }
  }
  void add_force(float $fx,float $fy,float $fz){
    fx += $fx; fy += $fy; fz += $fz; fn++;
  }
  void average_forces(){
    if(fn==0){ return; }
    fx /= fn; fy /= fn; fz /= fn;
  }
  void reset_forces(){
    fx = 0; fy = 0; fz = 0; fn = 0;
  }
  void step(){
    average_forces();
    v.vx = x+fx; v.vy = y+fy; v.vz = z+fz;
    v.unitize();
    v.scale(radius);
    move_to(v.vx,v.vy,v.vz);
    reset_forces();
  }
  void render(){
    stroke(255,100,100,100);
    v.render(zero_point);
    stroke(255);
    super.render();
  }
}
